# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1069.175.8 -> 1.1069.175.9 # drivers/char/agp/agpgart_be.c 1.41.1.25 -> 1.41.1.26 # drivers/char/agp/agp.h 1.27 -> 1.27.1.1 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 04/01/14 eranian@hpl.hp.com 1.1069.200.7 # ia64: Fix PFM_WRITE_PMCS failure in system-wide mode when PMC12 is zero # # - fixes a typo in pfm_write_pmcs() by which we were not using the # correct index variable to check for the default value of a PMC. # This caused calls to PFM_WRITE_PMCS to fail in system wide mode # when PMC12 is programmed to be zero. # -------------------------------------------- # 04/01/14 bjorn_helgaas@hp.com 1.1069.200.8 # ia64 HP iommu: add "sx1000" detection (no functional change). # -------------------------------------------- # 04/01/14 bjorn.helgaas@hp.com 1.1069.200.9 # ia64: work around a menuconfig bug. # # Re-order "HP" and "HP-simulator" to workaround menuconfig bug. If "HP-simulator" # appears first, menuconfig selects it when the user selects "HP". # -------------------------------------------- # 04/01/14 kaos@sgi.com 1.1069.200.10 # [PATCH] ia64: fix deadlock in ia64_mca_cmc_int_caller() # # smp_call_function() must not be called from interrupt context (can # deadlock on tasklist_lock). Use keventd to call smp_call_function(). # -------------------------------------------- # 04/01/14 tony.luck@intel.com 1.1069.200.11 # [PATCH] ia64: enable recovery from TLB errors # # Here's the updated version of the MCA TLB recovery patch. # -------------------------------------------- # 04/01/14 kaos@sgi.com 1.1069.200.12 # [PATCH] ia64: Avoid double clear of CMC/CPE records # # Credit to Ben Woodard . # -------------------------------------------- # 04/01/14 steiner@sgi.com 1.1069.200.13 # [PATCH] ia64: fix ia64_ctx.lock deadlock # # I hit a deadlock involving the ia64_ctx.lock. The lock # may be taken in interrupt context to process an IPI from smp_flush_tlb_mm. # -------------------------------------------- # 04/01/14 arun.sharma@intel.com 1.1069.200.14 # [PATCH] ia64: ia32 sigaltstack() fix # # The attached patch fixes a bug introduced by the earlier patch to # handle the differences between ia32 and ia64 in the definition of # MINSIGSTKSZ. # -------------------------------------------- # 04/01/14 bjorn.helgaas@hp.com 1.1069.200.15 # ia64: Fix system type selection to workaround menuconfig bug (select "HP", # get "HP-simulator"). # -------------------------------------------- # 04/01/14 bjorn.helgaas@hp.com 1.1069.200.16 # ia64: Fix broken merge (remove mmu_gathers[] defn) # -------------------------------------------- # 04/01/14 bjorn.helgaas@hp.com 1.1069.200.17 # ia64: Skip zero-length resources in PCI root bridge _CRS # -------------------------------------------- # 04/01/14 alex.williamson@hp.com 1.1069.200.18 # [PATCH] ia64: sba_iommu update # # This patch does a couple things: # * Allows iommu page size different than PAGE_SIZE. This was # largely done by Bjorn. The motivation for this is that sx1000 # hardware officially only supports use of the iommu with a 4k # page size. Thus the default is now 4k for sx1000 and PAGE_SIZE # for zx1. # * Cleanup the runtime statistics gathering such that we can turn # it on for some info w/o impacting runtime performance. # -------------------------------------------- # 04/01/14 bjorn.helgaas@hp.com 1.1137 # Merge hp.com:/home/helgaas/linux/ia64-extras # into hp.com:/home/helgaas/linux/linux-ia64-2.4 # -------------------------------------------- # 04/01/14 bjorn.helgaas@hp.com 1.1138 # fix up sx1000 init function merge. # -------------------------------------------- # 04/01/15 marcelo@logos.cnet 1.1069.176.104 # Merge bk://bk.phunnypharm.org/ieee1394-2.4 # into logos.cnet:/home/marcelo/bk/linux-2.4 # -------------------------------------------- # 04/01/15 khali@linux-fr.org 1.1069.176.105 # [PATCH] i2c cleanup: saa7146.h should include i2c-old.h, not i2c.h. # # * saa7146.h should include i2c-old.h, not i2c.h. # -------------------------------------------- # 04/01/15 khali@linux-fr.org 1.1069.176.106 # [PATCH] i2c cleanup: i2c-core fixes # # This patch defines I2C_SMBUS_BLOCK_MAX and I2C_SMBUS_I2C_BLOCK_MAX, # those values were previously hardcoded in several places. # # Part of the work was done by Kyösti Mälkki. Original comment follows: # *** # Message block size. # *** # # The patch also fixes an incorrect error message and a potential buffer # overrun. # -------------------------------------------- # 04/01/15 alex.williamson@hp.com 1.1069.200.19 # ia64: sba_iommu: use memparse, long double # -------------------------------------------- # 04/01/15 bjorn.helgaas@hp.com 1.1069.200.20 # ia64: sba_iommu: print note about reserving IOVA space for agpgart. # -------------------------------------------- # 04/01/15 bjorn.helgaas@hp.com 1.1069.200.21 # ia64: Export acpi_hp_csr_space() for modular agpgart. # -------------------------------------------- # 04/01/15 bjorn.helgaas@hp.com 1.1069.175.9 # agpgart: Fix HP ZX1 AGP 8X bridge support. # -------------------------------------------- # diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h --- a/drivers/char/agp/agp.h Thu Jan 15 13:52:22 2004 +++ b/drivers/char/agp/agp.h Thu Jan 15 13:52:22 2004 @@ -535,10 +535,6 @@ #define HP_ZX1_TCNFG 0x318 #define HP_ZX1_PDIR_BASE 0x320 -/* HP ZX1 LBA registers */ -#define HP_ZX1_AGP_STATUS 0x64 -#define HP_ZX1_AGP_COMMAND 0x68 - /* ATI register */ #define ATI_APBASE 0x10 #define ATI_GART_MMBASE_ADDR 0x14 diff -Nru a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c --- a/drivers/char/agp/agpgart_be.c Thu Jan 15 13:52:22 2004 +++ b/drivers/char/agp/agpgart_be.c Thu Jan 15 13:52:22 2004 @@ -5020,6 +5020,7 @@ static struct _hp_private { volatile u8 *ioc_regs; volatile u8 *lba_regs; + int lba_cap_offset; u64 *io_pdir; // PDIR for entire IOVA u64 *gatt; // PDIR just for GART (subset of above) u64 gatt_entries; @@ -5072,6 +5073,7 @@ hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { + /* Normal case when no AGP device in system */ hp->gatt = 0; hp->gatt_entries = 0; printk(KERN_ERR PFX "No reserved IO PDIR entry found; " @@ -5117,12 +5119,13 @@ return 0; } -static int __init hp_zx1_ioc_init(u64 ioc_hpa, u64 lba_hpa) +static int __init hp_zx1_ioc_init(u64 hpa) { struct _hp_private *hp = &hp_private; - hp->ioc_regs = ioremap(ioc_hpa, 1024); - hp->lba_regs = ioremap(lba_hpa, 256); + hp->ioc_regs = ioremap(hpa, 1024); + if (!hp->ioc_regs) + return -ENOMEM; /* * If the IOTLB is currently disabled, we can take it over. @@ -5136,6 +5139,50 @@ return hp_zx1_ioc_shared(); } +static int +hp_zx1_lba_find_capability(volatile u8 *hpa, int cap) +{ + u16 status; + u8 pos, id; + int ttl = 48; + + status = INREG16(hpa, PCI_STATUS); + if (!(status & PCI_STATUS_CAP_LIST)) + return 0; + pos = INREG8(hpa, PCI_CAPABILITY_LIST); + while (ttl-- && pos >= 0x40) { + pos &= ~3; + id = INREG8(hpa, pos + PCI_CAP_LIST_ID); + if (id == 0xff) + break; + if (id == cap) + return pos; + pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT); + } + return 0; +} + +static int __init hp_zx1_lba_init(u64 hpa) +{ + struct _hp_private *hp = &hp_private; + int cap; + + hp->lba_regs = ioremap(hpa, 256); + if (!hp->lba_regs) + return -ENOMEM; + + hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP); + + cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff; + if (cap != PCI_CAP_ID_AGP) { + printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", + cap, hp->lba_cap_offset); + return -ENODEV; + } + + return 0; +} + static int hp_zx1_fetch_size(void) { int size; @@ -5151,7 +5198,7 @@ struct _hp_private *hp = &hp_private; agp_bridge.gart_bus_addr = hp->gart_base; - agp_bridge.mode = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS); + agp_bridge.mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS); if (hp->io_pdir_owner) { OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, @@ -5171,10 +5218,13 @@ { struct _hp_private *hp = &hp_private; - if (hp->io_pdir_owner) - OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0); - iounmap((void *) hp->ioc_regs); - iounmap((void *) hp->lba_regs); + if (hp->ioc_regs) { + if (hp->io_pdir_owner) + OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0); + iounmap((void *) hp->ioc_regs); + } + if (hp->lba_regs) + iounmap((void *) hp->lba_regs); } static void hp_zx1_tlbflush(agp_memory * mem) @@ -5294,18 +5344,23 @@ struct _hp_private *hp = &hp_private; u32 command; - command = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS); + command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS); command = agp_collect_device_status(mode, command); command |= 0x00000100; - OUTREG32(hp->lba_regs, HP_ZX1_AGP_COMMAND, command); + OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command); agp_device_command(command, 0); } static int __init hp_zx1_setup(u64 ioc_hpa, u64 lba_hpa) { + struct _hp_private *hp = &hp_private; + int error; + + memset(hp, 0, sizeof(*hp)); + agp_bridge.dev_private_data = NULL; agp_bridge.size_type = FIXED_APER_SIZE; agp_bridge.needs_scratch_page = FALSE; @@ -5330,7 +5385,16 @@ fake_bridge_dev.vendor = PCI_VENDOR_ID_HP; fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA; - return hp_zx1_ioc_init(ioc_hpa, lba_hpa); + error = hp_zx1_ioc_init(ioc_hpa); + if (error) + goto fail; + + error = hp_zx1_lba_init(lba_hpa); + +fail: + if (error) + hp_zx1_cleanup(); + return error; } static acpi_status __init hp_zx1_gart_probe(acpi_handle obj, u32 depth, void *context, void **ret) @@ -5344,7 +5408,7 @@ status = acpi_hp_csr_space(obj, &lba_hpa, &length); if (ACPI_FAILURE(status)) - return AE_OK; + return AE_OK; /* keep looking for another bridge */ /* Look for an enclosing IOC scope and find its CSR space */ handle = obj; @@ -5380,7 +5444,7 @@ (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa); hp_zx1_gart_found = 1; - return AE_CTRL_TERMINATE; + return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */ } static int __init